import { Component, OnInit, Injector, NgZone } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { Subject, Observable, Subscribable, Subscription, BehaviorSubject } from 'rxjs';
import { tap, filter, share, map } from 'rxjs/operators';
import { HttpEventType, HttpEvent, HttpProgressEvent } from '@angular/common/http';

import { markAllAsTouched, formGroupToFormData } from 'app/modules/base/helper';
import { ClientUpdateService } from '../../services/client-update.service';
import { ListBase } from 'app/modules/base/list-base';
import { SweetAlertService } from 'app/modules/share/services/sweet-alert.service';
import { SubjectSubscriber } from 'rxjs/internal/Subject';
import { ToasterService } from '../../../share/services/toaster.service';
import { version } from 'punycode';
import { group } from '@angular/animations';
import { ActivatedRoute, Router } from '@angular/router';
@Component({
	selector: 'm-client-update',
	templateUrl: './client-update.component.html',
	styleUrls: ['./client-update.component.scss'],
})
export class ClientUpdateComponent implements OnInit {
	constructor(
		private fb: FormBuilder,
		private zone: NgZone,
		private sweet: SweetAlertService,
		private clientUpdater: ClientUpdateService,
		private toast: ToasterService,
		private route: ActivatedRoute,
	) { }
	formGroup = this.fb.group({
		version: ['', Validators.required],
		file: ['', Validators.required],
		architecture: [''],
	});
	dataSource = this.clientUpdater;
	uploadSubject: Subscription;
	progress$ = new BehaviorSubject<number>(0);
	architectureList$ = this.route.data.pipe(map((data) => data['architecture_list']));
	objectKeys = Object.keys;
	architectureSelect: string;
	readonly: boolean;

	ngOnInit() { }

	async submit() {
		this.readonly = false;
		markAllAsTouched(this.formGroup);
		if (this.formGroup.invalid) {
			return;
		}
		const data = formGroupToFormData(this.formGroup);
		try {
			await new Promise((resolve, reject) => {
				this.uploadSubject = this.clientUpdater
					.upload(data)
					.pipe(
						filter(event => event.type === HttpEventType.UploadProgress),
						map(event => event.loaded / event.total),
					)
					.subscribe(v => this.progress$.next(v), reject, resolve);
			});
		} finally {
			this.progress$.next(0);
		}
		this.sweet.alert('上传成功', { type: 'success' });
		this.formGroup.reset({ version: '', file: null });
	}

	upload() {
		this.architectureSelect = null;
		const fileControl = this.formGroup.get('file');
		fileControl.setValue(null);
		fileControl.markAsTouched();
		const input = document.createElement('input');
		input.type = 'file';
		input.accept = '.deb';
		input.click();
		input.addEventListener('change', e => {
			const fileNameArr = input.files[0].name.split('.');
			const byFileName = input.files[0].name && fileNameArr[fileNameArr.length - 1] === 'deb';
			const byType = input.files[0].type === 'application/x-deb';
			if (byFileName || byType) {
				fileControl.setValue(input.files[0]), { once: true }
				const fileName = input.files[0].name;
				const version = fileName.split("_")[2].split("-")[0]
				const architecture = fileName.split("_")[3]
				if (version && architecture) {
					this.formGroup.get('version').setValue(version);
					this.formGroup.get('architecture').setValue(architecture);
					let that = this;
					let isFind = false;
					this.architectureList$.subscribe(function (value) {
						Object.keys(value).forEach(key => {
							if (value[key].includes(architecture)) {
								that.architectureSelect = key;
								that.readonly = true;
								return isFind = true;
							}
						})
						if (!isFind) {
							that.readonly = false;
							that.toast.warn("架构不在指定类型中，请手动输入");
						}
					})
				} else {
					this.toast.warn("文件解析失败,请手动输入");
				}
				return
			}
			this.toast.warn("只可以上传.deb文件");
		});
	}
	cancel() {
		this.readonly = false;
		this.progress$.next(0);
		this.uploadSubject.unsubscribe();
	}
	async public() {
		await this.clientUpdater.publish();
		this.sweet.alert('已发布最新版本', { type: 'success' });
	}
	async delete(version: string, id: number) {
		if ((await this.sweet.confirm(`确定要删除版本[${version}]吗`)).dismiss) {
			return;
		}
		await this.clientUpdater.delete([id]);
	}
	resetForm() {
		this.formGroup.reset({ version: '', file: '', architecture: '' });
		this.readonly = false;
	}
}
